package com.handinfo.android.uicontrols;

import android.graphics.PointF;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;

import com.handinfo.android.DWGameManager;
import com.handinfo.android.core.graphics.DWScreen;
import com.handinfo.android.utils.Tools;

public class DWGestureRecognition implements OnGestureListener, OnDoubleTapListener
{

	private DWGestureListener m_gListener = null;

	private GestureDetector mGesture;//手势判定

	private byte m_scroll_state = 0;//滑动状态

//	private final byte SCROLL_STATE_NONE = 0;//无效滑动

	private final byte SCROLL_STATE_CLICK = 1;//点击滑动

	private final byte SCROLL_STATE_LONG = 2;//长按滑动

	private VelocityTracker mVelocityTracker = null;//速度检测

	private int mMinimumFlingVelocity;
	private int mMaximumFlingVelocity;

	private float mLastMotionY;
	private float mLastMotionX;

	public DWGestureRecognition(DWGestureListener gl)
	{
		if (gl == null) {
			throw new NullPointerException("DWGestureListener must not be null");
		}
		m_gListener = gl;
		mGesture = new GestureDetector(this);
		mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity();
		mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity();
	}
	
	private PointF getScalingPointF(PointF point) {
		return new PointF(getScalingX(point.x), getScalingY(point.y));
	}
	
	private PointF getScalingPointF(float x, float y) {
		return new PointF(getScalingX(x), getScalingY(y));
	}
	
	private float getScalingX(float x) {
//		float scalingX = ((float)DWScreen.Instance.m_width) / ((float)DWGameManager.Screen_Width);
		float scalingX = ((float)DWGameManager.Screen_Width) / ((float)DWScreen.Instance.m_width);
		return scalingX * x;
	}
	
	private float getScalingY(float y) {
		float scalingY = ((float)DWGameManager.Screen_Height) / ((float)DWScreen.Instance.m_height);
		return scalingY * y;
	}
	private long m_lp_start_time = 0;
	private long m_lp_cur_time = 0;
	private final int CLICK_DOWN_TIME = 300;
	private final int CLICK_DONW_RECT = 50;
	private long m_down_time = 0;//按下时间
	private float m_down_x = 0;//按下x
	private float m_down_y = 0;//按下y
	private final int MOVE_SPEED = 300;
	private final int MOVE_RECT = 50;
	private boolean m_is_long = false;//是否可以长按
	public void onTouch(MotionEvent event)
	{
		mGesture.onTouchEvent(event);
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		
		mVelocityTracker.addMovement(event);
		
		final VelocityTracker velocityTracker = mVelocityTracker;
		velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
		final float velocityX = velocityTracker.getXVelocity();
		final float velocityY = velocityTracker.getYVelocity();

		switch (event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				m_lp_start_time = System.currentTimeMillis();
				m_down_time = System.currentTimeMillis();
				m_down_x = event.getX();
				m_down_y = event.getY();
				m_is_long = true;
				break;
			case MotionEvent.ACTION_MOVE:
				float x = mLastMotionX - event.getX();
				float y = mLastMotionY - event.getY();
				m_lp_cur_time = System.currentTimeMillis();
				if (m_is_long && m_lp_cur_time - m_lp_start_time < 300) {
					if (Math.abs(x) > MOVE_RECT || Math.abs(y) > MOVE_RECT
							|| Math.abs(velocityX) > MOVE_SPEED || Math.abs(velocityY) > MOVE_SPEED) {
						m_is_long = false;
					} else {
						return;
					}
				}
				if (m_is_long && m_scroll_state == SCROLL_STATE_CLICK) {
					m_down_x = -100;
					m_down_y = -100;
					m_scroll_state = SCROLL_STATE_LONG;
					PointF start = new PointF(mLastMotionX, mLastMotionY);
					PointF end = new PointF(event.getX(), event.getY());
					m_gListener.onLongPress(getScalingPointF(start));
					m_gListener.onLongScroll(getScalingPointF(start), getScalingPointF(end), x, y);
				} else {
					PointF start = new PointF(mLastMotionX, mLastMotionY);
					PointF end = new PointF(event.getX(), event.getY());
					if (m_scroll_state == SCROLL_STATE_CLICK) {
						m_gListener.onScroll(getScalingPointF(start), getScalingPointF(end), x, y);
					} else if (m_scroll_state == SCROLL_STATE_LONG) {
						m_gListener.onLongScroll(getScalingPointF(start), getScalingPointF(end), x, y);
					}
				}
				break;
			case MotionEvent.ACTION_UP:
				float offsetx = Math.abs(event.getX() - m_down_x);
				float offsety = Math.abs(event.getY() - m_down_y);
				if (offsetx < CLICK_DONW_RECT && offsety < CLICK_DONW_RECT
						&& System.currentTimeMillis() - m_down_time < CLICK_DOWN_TIME) {
					m_gListener.onClick(getScalingPointF(new PointF(event.getX(), event.getY())));
				} else {
					PointF start = new PointF(mLastMotionX, mLastMotionY);
					PointF end = new PointF(event.getX(), event.getY());
					if (m_scroll_state == SCROLL_STATE_CLICK) {
						m_gListener.onFling(getScalingPointF(start), getScalingPointF(end), velocityX, velocityY);
					}
					else if (m_scroll_state == SCROLL_STATE_LONG) {
						m_gListener.onDrag(getScalingPointF(start), getScalingPointF(end), velocityX, velocityY);
					}
				}
				m_lp_start_time = 0;
				mVelocityTracker.recycle();
				mVelocityTracker = null;
				break;
		}
		mLastMotionX = event.getX();
		mLastMotionY = event.getY();
		m_gListener.onTouch(event, getScalingPointF(event.getX(), event.getY()));
	}

	public boolean onSingleTapConfirmed(MotionEvent e)
	{
		return false;
	}

	public boolean onDoubleTap(MotionEvent e)
	{
		return false;
	}

	public boolean onDoubleTapEvent(MotionEvent e)
	{
		m_gListener.onDoubleClick(getScalingPointF(e.getX(), e.getY()));
		return false;
	}

	public boolean onDown(MotionEvent e)
	{
		m_scroll_state = SCROLL_STATE_CLICK;
		m_gListener.onDown(getScalingPointF(e.getX(), e.getY()));
		return false;
	}

	public void onShowPress(MotionEvent e)
	{

	}

	public boolean onSingleTapUp(MotionEvent e)
	{
//		m_gListener.onClick(getScalingPointF(e.getX(), e.getY()));
		return false;
	}

	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
	{
		return false;
	}

	public void onLongPress(MotionEvent e)
	{
//		m_scroll_state = SCROLL_STATE_LONG;
//		m_gListener.onLongPress(getScalingPointF(e.getX(), e.getY()));
	}

	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
	{
		return false;
	}

	
}
